package ALBasicServer.ALProcess;

import java.util.LinkedList;

import ALBasicServer.ALProcess.SynTask.ALProcessStepActionMonoTask;
import ALBasicServer.ALProcess.SynTask.ALProcessStepFuncMonoTask;
import ALBasicServer.ALProcess.SynTask._AALProcessBasicMonoTask;
import ALBasicServer.ALServerSynTask.ALSynTaskManager;
import ALServerLog.ALServerLog;

/******************
 * 加载步骤的管理对象
 * @author mj
 *
 */
public class ALProcess extends _AALProcess implements _IALProcessAction
{
    /// <summary>
    /// 创建一个过程对象
    /// </summary>
    /// <returns></returns>
    public static ALProcess CreateProcess() { return CreateProcess(""); }
    public static ALProcess CreateProcess(String _processTag) { return new ALProcess(_processTag); }
    /// <summary>
    /// 创建一个多过程过程对象
    /// </summary>
    /// <returns></returns>
    public static ALMultiProcess CreateMultiProcess() { return CreateMultiProcess(""); }
    public static ALMultiProcess CreateMultiProcess(String _processTag) { return ALMultiProcess.CreateMultiProcess(_processTag); }
    /// <summary>
    /// 创建一个执行时再创建步骤的处理过程
    /// </summary>
    /// <param name="_process">返回一个步骤对象，当步骤对象设置完成的时候将完成本步骤</param>
    /// <returns></returns>
    public static ALActionProcess CreateActionProcess(_IALProcessSubProcess _process) { return CreateActionProcess(_process, ""); }
    public static ALActionProcess CreateActionProcess(_IALProcessSubProcess _process, String _processTag) { return ALActionProcess.CreateFuncProcess(_process, _processTag); }
    /// <summary>
    /// 创建一个步骤处理对象
    /// </summary>
    /// <returns></returns>
    public static ALStepProcess CreateStepProcess() { return CreateStepProcess(""); }
    public static ALStepProcess CreateStepProcess(String _processTag) { return ALStepProcess.CreateStepProcess(_processTag); }
    /// <summary>
    /// 创建一个使用回调调用完成的处理对象
    /// </summary>
    /// <returns></returns>
    public static ALDelegateProcess CreateDelegateProcess() { return CreateDelegateProcess(""); }
    public static ALDelegateProcess CreateDelegateProcess(String _processTag) { return ALDelegateProcess.CreateDelegateProcess(_processTag); }
    /// <summary>
    /// 创建一个使用回调调用完成的处理对象
    /// </summary>
    /// <returns></returns>
    public static ALResDelegateProcess CreateResDelegateProcess() { return CreateResDelegateProcess(""); }
    public static ALResDelegateProcess CreateResDelegateProcess(String _processTag) { return ALResDelegateProcess.CreateResDelegateProcess(_processTag); }

    /// <summary>
    /// 执行的任务队列
    /// </summary>
    private LinkedList<_AALProcessBasicMonoTask> _m_lDealTaskList;

    protected ALProcess(String _processTag)
    {
    	super(_processTag);
    	
        _m_lDealTaskList = new LinkedList<_AALProcessBasicMonoTask>();
    }
    
	/**************
	 * 单纯的一个纯函数处理
	 * 
	 * 这里直接处理完成
	 * @param _process
	 */
    @Override
	public void dealAction()
	{
    	_dealNextProcess();
	}

    /// <summary>
    /// 添加一个执行过程
    /// </summary>
    /// <param name="_process"></param>
    /// <returns></returns>
    public ALProcess addProcess(_AALProcess _process)
    {
        if(null == _process)
            return this;

        if(isRunning())
        {
            ALServerLog.Error("add process when process started!");
            return this;
        }

        synchronized (_m_lDealTaskList) {
            //加入队列返回
            _m_lDealTaskList.add(_process);
		}
        //设置父节点
        _process.setParentProcess(this);

        return this;
    }

    /// <summary>
    /// 增加一个过程处理，如果处理过程出现异常则调用失败处理
    /// </summary>
    /// <param name="_processAction"></param>
    /// <param name="_failDelegate"></param>
    /// <param name="_isFailContinue">是否出错了仍然继续</param>
    /// <returns>返回自身，可以继续添加步骤</returns>
    public ALProcess addActionProcess(_IALProcessAction _processAction)
    {
    	return addActionProcess(_processAction, null, true);
    }
    public ALProcess addActionProcess(_IALProcessAction _processAction, _IALProcessAction _failDelegate, boolean _isFailContinue)
    {
        if(isRunning())
        {
        	ALServerLog.Error("add process action when process started!");
            return this;
        }

        synchronized (_m_lDealTaskList) {
        	final _AALProcess dealProcess = this;
        	final boolean tmpIsFailContinue = _isFailContinue;
	        //创建任务放入队列
	        _m_lDealTaskList.add(new ALProcessStepActionMonoTask(_processAction, processTag(), _m_lDealTaskList.size(), this
	            , _failDelegate
	            , new _IALProcessAction() {
					@Override
					public void dealAction() {
		        		//失败不继续则设置进程被中断
						if(!tmpIsFailContinue)
			            	_m_cController._enable = false;

						if(null != getMonitor())
							getMonitor().onProcessFailStop(dealProcess);
					}
				}));
        }

        return this;
    }
    public ALProcess addFuncProcess(_ITALProcessFunc<Boolean> _processAction)
    {
    	return addFuncProcess(_processAction, null, true);
    }
    public ALProcess addFuncProcess(_ITALProcessFunc<Boolean> _processAction, _IALProcessAction _failDelegate, boolean _isFailContinue)
    {
        if(isRunning())
        {
        	ALServerLog.Error("add process when process started!");
            return this;
        }

        synchronized (_m_lDealTaskList) {
        	final _AALProcess dealProcess = this;
        	final boolean tmpIsFailContinue = _isFailContinue;
	        //创建任务放入队列
	        _m_lDealTaskList.add(new ALProcessStepFuncMonoTask(_processAction, processTag(), _m_lDealTaskList.size(), this
	            , _failDelegate
	            , new _IALProcessAction() {
					@Override
					public void dealAction() {
		        		//失败不继续则设置进程被中断
						if(!tmpIsFailContinue)
			            	_m_cController._enable = false;
						
						if(null != getMonitor())
							getMonitor().onProcessFailStop(dealProcess);
					}
				}));
        }

        return this;
    }

    /// <summary>
    /// 添加一个异步处理函数
    /// </summary>
    /// <param name="_process"></param>
    /// <returns></returns>
    public ALProcess addActionProcess(_IALProcessSubProcess _process)
    {
        return addActionProcess(_process, "");
    }
    public ALProcess addActionProcess(_IALProcessSubProcess _process, String _processTag)
    {
        if (null == _process)
            return this;

        if (isRunning())
        {
            ALServerLog.Error("add process when process started!");
            return this;
        }

        ALActionProcess funcProcess = CreateActionProcess(_process, _processTag);
        
        synchronized (_m_lDealTaskList) {
	        //加入队列返回
	        _m_lDealTaskList.add(funcProcess);
        }
        
        //设置父节点
        funcProcess.setParentProcess(this);

        return this;
    }

    /// <summary>
    /// 添加使用回调确认完成的处理
    /// </summary>
    /// <param name="_delegateAction"></param>
    /// <param name="_failDelegate"></param>
    /// <param name="_isFailContinue"></param>
    /// <returns></returns>
    public ALProcess addDelegateProcess(_IALProcessDelegate _delegateAction)
    {
        return addDelegateProcess(_delegateAction, "", null, true);
    }
    public ALProcess addDelegateProcess(_IALProcessDelegate _delegateAction, _IALProcessAction _failDelegate, boolean _isFailContinue)
    {
        return addDelegateProcess(_delegateAction, "", _failDelegate, _isFailContinue);
    }
    public ALProcess addDelegateProcess(_IALProcessDelegate _delegateAction, String _processTag)
    {
        return addDelegateProcess(_delegateAction, _processTag, null, true);
    }
    public ALProcess addDelegateProcess(_IALProcessDelegate _delegateAction, String _processTag, _IALProcessAction _failDelegate, boolean _isFailContinue)
    {
        if (isRunning())
        {
            ALServerLog.Error("add process action when process started!");
            return this;
        }

        addProcess(ALProcess.CreateDelegateProcess(_processTag).setProcess(_delegateAction, _failDelegate, _isFailContinue));

        return this;
    }

    /// <summary>
    /// 添加使用回调确认完成的处理
    /// </summary>
    /// <param name="_delegateAction"></param>
    /// <param name="_failDelegate"></param>
    /// <param name="_isFailContinue"></param>
    /// <returns></returns>
    public ALProcess addResDelegateProcess(_IALProcessResDelegate _delegateAction)
    {
        return addResDelegateProcess(_delegateAction, "", null, true);
    }
    public ALProcess addResDelegateProcess(_IALProcessResDelegate _delegateAction, _IALProcessAction _failDelegate, boolean _isFailContinue)
    {
        return addResDelegateProcess(_delegateAction, "", _failDelegate, _isFailContinue);
    }
    public ALProcess addResDelegateProcess(_IALProcessResDelegate _delegateAction, String _processTag)
    {
        return addResDelegateProcess(_delegateAction, _processTag, null, true);
    }
    public ALProcess addResDelegateProcess(_IALProcessResDelegate _delegateAction, String _processTag, _IALProcessAction _failDelegate, boolean _isFailContinue)
    {
        if (isRunning())
        {
            ALServerLog.Error("add process action when process started!");
            return this;
        }

        addProcess(ALProcess.CreateResDelegateProcess(_processTag).setProcess(_delegateAction, _failDelegate, _isFailContinue));

        return this;
    }

    /// <summary>
    /// 一次性加入多个步骤，同时每个步骤完成时会调用对应的回调
    /// 最终所有步骤完成表示大步骤完成
    /// </summary>
    /// <param name="_processAction"></param>
    /// <returns></returns>
    public ALProcess addStepProcess(_IALProcessDelegate[] _stepAction)
    {
        return addStepProcess("", _stepAction);
    }
    public ALProcess addStepProcess(String _processTag, _IALProcessDelegate[] _stepAction)
    {
        if (isRunning())
        {
            ALServerLog.Error("add process when process started!");
            return this;
        }

        //创建任务放入队列
        ALStepProcess stepP = CreateStepProcess(_processTag);
        for (int i = 0; i < _stepAction.length; i++)
        {
            if (null == _stepAction[i])
                continue;

            stepP.addProcess(_stepAction[i]);
        }

        //添加到节点
        addProcess(stepP);

        return this;
    }

    /// <summary>
    /// 一次性加入多个并行操作
    /// </summary>
    /// <param name="_processAction"></param>
    /// <returns></returns>
    public ALProcess addMultiProcess(_IALProcessAction[] _processAction)
    {
        return addMultiProcess("", _processAction);
    }
    public ALProcess addMultiProcess(String _processTag, _IALProcessAction[] _processAction)
    {
        if(isRunning())
        {
            ALServerLog.Error("add process when process started!");
            return this;
        }

        //创建任务放入队列
        ALMultiProcess multiP = CreateMultiProcess(_processTag);
        for(int i = 0; i < _processAction.length; i++)
        {
            if(null == _processAction[i])
                continue;

            multiP.addMultiProcess(_processAction[i]);
        }

        //添加到节点
        addProcess(multiP);

        return this;
    }

    public ALProcess addMultiProcess(_ITALProcessFunc<Boolean>[] _processAction)
    {
        return addMultiProcess("", _processAction);
    }
    public ALProcess addMultiProcess(String _processTag, _ITALProcessFunc<Boolean>[] _processAction)
    {
        if(isRunning())
        {
            ALServerLog.Error("add process when process started!");
            return this;
        }

        //创建任务放入队列
        ALMultiProcess multiP = CreateMultiProcess(_processTag);
        for(int i = 0; i < _processAction.length; i++)
        {
            if(null == _processAction[i])
                continue;

            multiP.addMultiProcess(_processAction[i]);
        }

        //添加到节点
        addProcess(multiP);

        return this;
    }

    public ALProcess addMultiProcess(ALProcess[] _process)
    {
        return addMultiProcess("", _process);
    }
    public ALProcess addMultiProcess(String _processTag, ALProcess[] _process)
    {
        if(isRunning())
        {
            ALServerLog.Error("add process when process started!");
            return this;
        }

        //创建任务放入队列
        ALMultiProcess multiP = CreateMultiProcess(_processTag);
        for(int i = 0; i < _process.length; i++)
        {
            if(null == _process[i])
                continue;

            multiP.addProcess(_process[i]);
        }

        //添加到节点
        addProcess(multiP);

        return this;
    }

    /// <summary>
    /// 重置处理
    /// </summary>
    @Override
    protected void _onDiscard()
    {
        synchronized (_m_lDealTaskList) {
        	_m_lDealTaskList.clear();
        }
    }

    /// <summary>
    /// 获取出来可以在监控对象外围补充输出的信息
    /// </summary>
    @Override
    protected String _processMonitorExInfo()
    {
        return "[ALProcess: [" + _m_lDealTaskList.size() + "] Task Remain]";
    }

    /// <summary>
    /// 执行任务
    /// </summary>
    @Override
    protected void _dealProcess(_IALProcessMonitor _monitor)
    {
        //设置监控对象
    	setMonitor(_monitor);

        //处理下一个任务
        _dealNextProcess();
    }
    /// <summary>
    /// 处理下一个任务
    /// </summary>
    protected void _dealNextProcess()
    {
        //如果已经不继续执行，则直接返回
        if (!_m_cController._enable)
        {
            //此时直接执行过程完成
            _onProcessDone();
            return;
        }
        
        if(null == _m_lDealTaskList || _m_lDealTaskList.size() <= 0)
        {
            //完结
            _onProcessDone();
            return;
        }

        _AALProcessBasicMonoTask processObj = null;
        synchronized (_m_lDealTaskList) {
	        //取出第一个进行处理
	        processObj = _m_lDealTaskList.getFirst();
	        while(null == processObj && !_m_lDealTaskList.isEmpty())
	        {
	            //移除第一个
	            _m_lDealTaskList.removeFirst();
	            //重新获取第一个对象
	            processObj = _m_lDealTaskList.getFirst();
	        }
        }

        //如有数据则删除第一个对象
        if(null == processObj)
        {
            _onProcessDone();
            return;
        }

        synchronized (_m_lDealTaskList) {
	        //移除数据
	        _m_lDealTaskList.removeFirst();
        }

        //强制刷新监控步骤的开始时间
        _forceRefreshProcessStartTime();
        //判断对象是否步骤类，是则需要设置监控对象
        processObj.setMonitor(getMonitor());

        //进行数据的处理
        ALSynTaskManager.getInstance().regTask(processObj);
    }

    /// <summary>
    /// 当子处理对象完成时的处理
    /// </summary>
    @Override
    protected void _onChildDone()
    {
        _dealNextProcess();
    }

    /// <summary>
    /// 完成的处理，需要放回缓存池
    /// </summary>
    @Override
    protected void _onDone()
    {
    }
}
